/*******************************************************************************
 *  Copyright (c) 2010 Chase Technology Ltd.
 *  
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the GNU General Public License v3.0
 *  which is available at http://www.gnu.org/licenses/
 * 
 * Contributors:
 *     Doug Satchwell - initial API and implementation
 *******************************************************************************/
package org.jfunction.ui.internal.editor;

import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.MonoReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
import org.eclipse.ui.texteditor.spelling.ISpellingProblemCollector;
import org.eclipse.ui.texteditor.spelling.SpellingReconcileStrategy;
import org.eclipse.ui.texteditor.spelling.SpellingService;
import org.jfunction.internal.parser.JFunctionPartitionScanner;
import org.jfunction.ui.internal.JFunctionUIPlugin;

public class JFunctionEditorSourceViewerConfiguration extends TextSourceViewerConfiguration {
	private static ITokenScanner scenarioScanner;
	private static ITokenScanner examplesScanner;
	private static ITokenScanner stringScanner;
	private IReconciler reconciler;
	private ISharedTextColors sharedColors;
	private JFunctionEditor editor;

	public JFunctionEditorSourceViewerConfiguration(ISharedTextColors sharedColors,
			IPreferenceStore store) {
		super(store);
		this.sharedColors = sharedColors;
	}

	public JFunctionEditorSourceViewerConfiguration(ISharedTextColors sharedColors,
			IPreferenceStore store, JFunctionEditor editor) {
		super(store);
		this.sharedColors = sharedColors;
		this.editor = editor;
	}

	@Override
	public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
		return JFunctionDocumentProvider.JFUNCTION_PARTITIONING;
	}
	
	@Override
	public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
		return new String[] {
			JFunctionPartitionScanner.SCENARIO,
			JFunctionPartitionScanner.EXAMPLES
		};
	}
	
	@Override
	public String[] getDefaultPrefixes(ISourceViewer sourceViewer, String contentType) 
	{
		return new String[] {"//",""};
	}
		
	@Override
	public IReconciler getReconciler(ISourceViewer sourceViewer)
	{
		if (!EditorsUI.getPreferenceStore().getBoolean(SpellingService.PREFERENCE_SPELLING_ENABLED))
			return null;

		if (reconciler == null)
		{
			SpellingReconcileStrategy spellingStrategy= new SpellingReconcileStrategy(sourceViewer, EditorsUI.getSpellingService()){
				protected ISpellingProblemCollector createSpellingProblemCollector() {
					IAnnotationModel model= getAnnotationModel();
					if (model == null)
						return null;
					return new JFunctionSpellingProblemCollector(model,getDocument(), 
						JFunctionDocumentProvider.JFUNCTION_PARTITIONING, 
						new String[]{JFunctionPartitionScanner.SCENARIO}
					);
				}
			};
			
			CompositeReconcilingStrategy strategy = new CompositeReconcilingStrategy();
//			
//			boolean builderFound = P4Core.isBuilderEnabled();
//			if (builderFound && editor != null)
//			{
//				IFile file = (IFile)editor.getEditorInput().getAdapter(IFile.class);
//				try {
//					if (file != null && file.getProject().hasNature(P4Nature.NATURE_ID)) // && P4Core.isBuilderEnabled())
//					{
//						builderFound = true;
//						
//						strategy.setReconcilingStrategies(new IReconcilingStrategy[]{
//							spellingStrategy,
//							editor.strategy // the compiling strategy
//						});
//						reconciler = new MonoReconciler(strategy,true);
//					}
//				} catch (CoreException e) {
//					Plugin.log(e);
//				}
//			} 
//			else
//			{ // fall back to just spelling
				strategy.setReconcilingStrategies(new IReconcilingStrategy[]{
					spellingStrategy
				});
					
				reconciler = new MonoReconciler(strategy,false);
//			}
		}
		
		return reconciler;		
	}

	protected void addDamagerRepairer(PresentationReconciler reconciler, ITokenScanner commentScanner, String contentType) {
		DefaultDamagerRepairer commentDamagerRepairer= new DefaultDamagerRepairer(commentScanner);
		reconciler.setDamager(commentDamagerRepairer, contentType);
		reconciler.setRepairer(commentDamagerRepairer, contentType);
	}
	
	@Override
	public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
		PresentationReconciler reconciler= new PresentationReconciler();
		reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
		
		addDamagerRepairer(reconciler, getScenarioScanner(sharedColors), JFunctionPartitionScanner.SCENARIO);
		addDamagerRepairer(reconciler, getExamplesScanner(sharedColors), JFunctionPartitionScanner.EXAMPLES);
		
		return reconciler;
	}

	private static synchronized ITokenScanner getScenarioScanner(ISharedTextColors sharedColors) 
	{
		if (scenarioScanner == null)
			scenarioScanner = new ColourScenarioScanner(JFunctionUIPlugin.getKeywords(),sharedColors);
		return scenarioScanner;
	}

	private static synchronized ITokenScanner getExamplesScanner(ISharedTextColors sharedColors) 
	{
		if (examplesScanner == null)
			examplesScanner = new ColourExamplesScanner(JFunctionUIPlugin.getKeywords(), sharedColors);
		return examplesScanner;
	}
//	
//	private static synchronized ITokenScanner getP4StringScanner(ISharedTextColors sharedColors) 
//	{
//		if (stringScanner == null)
//		{
//			RuleBasedScanner scanner = new RuleBasedScanner();
//			IToken defaultToken = new Token(new TextAttribute(sharedColors.getColor(P4ColorConstants.STRING)));
//			scanner.setDefaultReturnToken(defaultToken);
//			stringScanner = scanner;
//		}
//		return stringScanner;
//	}


	/**
	 * Returns the information presenter control creator. The creator is a factory creating the
	 * presenter controls for the given source viewer. This implementation always returns a creator
	 * for <code>DefaultInformationControl</code> instances.
	 * 
	 * @return an information control creator
	 * @since 3.1
	 */
	public static IInformationControlCreator getInformationPresenterControlCreator() {
		return new IInformationControlCreator() {
			public IInformationControl createInformationControl(Shell parent) {
				int shellStyle= SWT.RESIZE;
				int style= SWT.V_SCROLL | SWT.H_SCROLL;
				return new DefaultInformationControl(parent, shellStyle, style, new HTMLTextPresenter(false));
			}
		};
	}
}
